SAMでAPI Gateway(REST API)のデフォルトエンドポイントを無効化する
いわさです。
以下の記事でmTLS + カスタムドメインのAPI GatewayをSAMでデプロイしました。
しかし、デフォルトエンドポイントが無効化出来ていませんでした。
この記事ではデフォルトエンドポイントの無効化方法をためします。
DisableExecuteApiEndpointはうまくいかない?
SAMではこのための設定値が用意されています。
AWS::Serverless::Api - AWS Serverless Application Model
DisableExecuteApiEndpoint
クライアントがデフォルトの execute-api エンドポイント (https://{api_id}.execute-api.{region}.amazonaws.com) を使用して API を呼び出すことができるかどうかを指定します。デフォルトで、クライアントはデフォルトのエンドポイントを使用して API を呼び出すことができます。クライアントが API の呼び出しにカスタムドメイン名以外を使用しないようにするには、デフォルトのエンドポイントを無効にします。タイプ: ブール
必須: いいえ
AWS CloudFormation との互換性: このプロパティは、AWS::ApiGateway::RestApi リソースの DisableExecuteApiEndpoint プロパティに直接渡されます。
このプロパティ早速ためしてみましょう。
Api: Type: AWS::Serverless::Api Properties: Name: !Ref ApiName EndpointConfiguration: REGIONAL OpenApiVersion: 3.0.1 StageName: iwasa-stage DefinitionBody: Fn::Transform: Name: AWS::Include Parameters: Location: ./openapi.json Domain: DomainName: !Ref CustomDomainName CertificateArn: !Ref Certificate EndpointConfiguration: REGIONAL MutualTlsAuthentication: TruststoreUri: !Ref TrustStoreS3Uri Route53: DistributionDomainName: !Ref CustomDomainName HostedZoneId: !Ref HostedZoneId SecurityPolicy: TLS_1_2 DisableExecuteApiEndpoint: true Certificate: Type: AWS::CertificateManager::Certificate Properties: DomainName: !Ref CustomDomainName DomainValidationOptions: - DomainName: !Ref CustomDomainName HostedZoneId: !Ref HostedZoneId ValidationMethod: DNS
しかし、デフォルトエンドポイントが無効化されていません。
こ、これは...
AWS::ApiGateway::RestApi リソースの DisableExecuteApiEndpoint プロパティに渡されない
ドキュメントでは、RestApiリソースのDisableExecuteApiEndpointプロパティに渡されるとされていますが、SAMのスタックから展開されたCloudFormationを確認してみましょう。
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "---", "Parameters": { : }, "Resources": { "Api": { "Type": "AWS::ApiGateway::RestApi", "Metadata": { "SamResourceId": "Api" }, "Properties": { "Body": { "paths": { "/": { "get": { "x-amazon-apigateway-integration": { "httpMethod": "GET", "passthroughBehavior": "when_no_match", "type": "http_proxy", "uri": "http://checkip.amazonaws.com", "responses": { "default": { "statusCode": "200" } } }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Empty" } } }, "description": "200 response" } } } } }, "openapi": "3.0.1", "components": { "schemas": { "Empty": { "type": "object", "title": "Empty Schema" } } }, "x-amazon-apigateway-endpoint-configuration": { "disableExecuteApiEndpoint": true } }, "Name": { "Ref": "ApiName" }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] } } }, : } }
AWS::ApiGateway::RestApi
のDisableExecuteApiEndpoint
プロパティには値は渡されていないですね。
ただし、(代わりに?)OpenAPIドキュメントのx-amazon-apigateway-endpoint-configuration.disableExecuteApiEndpoint
が設定されています。
一見すると動作しそうにも見えるのですが、実はこの設定値、Swagger2.0は最上位ベンダー拡張に存在する必要があるので上記のとおりで良いのですが、OpenAPI3.0ではサーバーオブジェクトのベンダー拡張の下に存在する必要があるそうです。
OpenAPIを使っている場合は直接指定する
よって、ここではSAMのDisableExecuteApiEndpointプロパティは使わずに、OpenAPIドキュメントへ以下のように直接反映させることが現時点の解決策になります。
{ "openapi" : "3.0.1", "servers": [ { "x-amazon-apigateway-endpoint-configuration": { "disableExecuteApiEndpoint": true } } ], "paths" : { : }, "components" : { : } }
デプロイしてみましょう。
お、デフォルトエンドポイントが無効化されている!
cURLでも確認してみます。
$ curl https://apihoge.tak1wa.com curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to apihoge.tak1wa.com:443 $ curl --key ./keys/my_client.key --cert ./keys/my_client.pem https://apihoge.tak1wa.com 120.51.74.235 $ curl https://4pqf8o4iqj.execute-api.ap-northeast-1.amazonaws.com/iwasa-stage curl: (6) Could not resolve host: 4pqf8o4iqj.execute-api.ap-northeast-1.amazonaws.com
良さそうです。
さいごに
本日はSAMでデフォルトエンドポイントを無効化する方法を確認してみました。
試してないのですが、Swagger2.0であればDisableExecuteApiEndpointが使えるのだと思います。
ドキュメントと挙動は異なりますが。
OpenAPIかSwaggerかなどでこのあたりの挙動が変わってくるとは盲点でした。